<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>汽油配平计算</title>
  <style>
    :root {
      --LB: #3AE;
      --TC: #FAFAFA;
      --TAG: #F5F5FC;
      --OL00: #A3A3A39A;
      --OL05: #EB45379A;
      --OL92: #FAC2309A;
      --OL95: #4286F39A;
      --OL98: #55AF7B9A;

      --SMBR: 4px;

      --PGSP: #3AA6;
    }

    button {
      margin: 0 .5em;
      padding: 6px 0.5em;
      font-family: Arial, Helvetica, sans-serif;
      font-weight: bolder;
      border: none;
      border-radius: var(--SMBR);
      color: var(--TC);
      background-color: var(--LB);
    }

    header {
      position: sticky;
      display: flex;
      top: 10px;
      z-index: 100;
      background: #FFF;
    }

    .tabs {
      display: flex;
    }

    a.tab,
    a.tab:visited {
      text-decoration: none;
    }

    .tab>div {
      margin: 2px;
      padding: 4px 2em;
      border-top-left-radius: 10px;
      border-top-right-radius: 10px;
      background-color: var(--TAG);
      color: var(--LB);
      text-decoration: none;
    }

    .tab:hover>div {
      background-color: var(--LB);
      color: var(--TC);
    }

    .Notice {
      padding-left: 2em;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 1.5em;
    }


    .page {
      display: none;
      position: relative;
    }

    .page:target {
      display: block;
    }

    .page-splitter {
      margin-top: 4em;
      min-height: 600px;
      width: .2em;
      background-color: var(--PGSP);
    }

    .right-th {
      display: flex;
      position: sticky;
      margin: .5em;
      /* box-sizing:border-box; */
      padding: 0 .5em .2em .5em;
      border-bottom: .2em solid var(--PGSP);
    }

    .right-td {
      display: block;
      margin: .2em;
      min-width: 15em;
    }

    .right-td select {
      width: 10em;
      margin: 0;
      padding: .2em;
      border: none;
      font-size: larger;
    }

    .right-td input[type="number"] {
      border: none;
      margin: 0;
      padding: 0;
      font-size: larger;
      text-align: center;
    }

    .right-td span {
      font-size: larger;
    }

    /* =====================  section 123 ====================== */
    .pg1-lt-li,
    .pg3-lt-li {
      margin: 1em;
    }

    #pg1-lt label,
    #pg3-lt label {
      margin-right: 0.5em;
    }

    #pg1-lt input,
    #pg3-lt input {
      padding: 4px;
      border-style: solid;
      border-radius: 4px;
      border-color: var(--LB);
    }


    div#pg1-two,
    div#pg3-two {
      display: flex;
    }

    div#pg1-lt,
    div#pg1-rt,
    div#pg3-lt,
    div#pg3-rt {
      margin: 2em 1em;
    }
  </style>
  <script>
    // localStroage DAO
    class LocalDAO {
      constructor(name) {
        this.name = name;
        Promise.resolve().then(() => {
          this.all();
        }).then(() => {
          if (!this.data)
            this.data = new Array();
          this.save();
        });
      }

      async all() {
        this.data = await JSON.parse(localStorage.getItem(this.name));
        return this.data;
      }

      async save() {
        localStorage.setItem(this.name, JSON.stringify(this.data));
        return true;
      }

      async add(row) {
        await this.all();
        this.data.push(row);
        await this.save();
        return true;
      }

      async delete(idx) {
        await this.all();
        this.data.splice(idx, 1);
        await this.save();
        return true;
      }

      async edit(idx, row) {
        await this.all();
        this.data[idx] = row;
        await this.save();
        return true
      }

      async read(idx) {
        await this.all();
        return this.data[idx];
      }

      async load(rows) {
        await this.all();
        this.data = this.data.concat(rows);
        await this.save();
        return true
      }

      async clear() {
        // await localStorage.removeItem(this.name);
        this.data.length = 0;
        await this.save();
        return true;
      }
    };

    /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     ** *                                                               *
     ** *          Blobal Bills & Qutoas are alert Below                *
     ** *                                                               *
     ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     */

    // ID for convenience
    const ID = id => document.querySelector('#' + id);

    const bindEdit = (htmlElement, handler) => {
      /* ======= double click Listener 双击监听 =============
      
      let lastClick = Date.now(), curClick;
      const fnDoubleClick = () => {
          curClick = Date.now();
          setTimeout(() => { lastClick = curClick; }, 50);
          return curClick - lastClick <= 500
      };
      */
      htmlElement.addEventListener('dblclick', function () { this.readOnly = false; });
      htmlElement.addEventListener('blur', function () {
        this.readOnly = true;
        handler();
      });
      htmlElement.addEventListener('mouseover', () => writeNotice('双击修改数值'));
      htmlElement.addEventListener('mouseout', () => writeNotice(''));

    }

    const bindDel = (htmlElement, handler, hoverNotice = '删除该行') => {

      htmlElement.addEventListener('click', function () { handler() });
      htmlElement.addEventListener('mouseover', () => writeNotice(hoverNotice));
      htmlElement.addEventListener('mouseout', () => writeNotice(''));

    }

    const bindSlt = (htmlElement, handler) => {
      htmlElement.addEventListener('dblclick', function () { this.disable = false; });
      htmlElement.addEventListener('mouseover', () => writeNotice('双击修改数值'));
      htmlElement.addEventListener('mouseout', () => writeNotice(''));
    }

        // document.body.addEventListener('click', () => {
        //     fnDoubleClick() && writeNotice("DoubleClick:" + lastClick);
        //     console.log('last click click')
        // })

        // Use dispatch event
        // const evnChanged = new CustomEvent('add', {detail: this._value + 1});

  </script>
</head>

<body>
  <header>
    <div class="tabs">
      <a class="tab" href="#pg1">
        <div>录入</div>
      </a>
      <a class="tab" href="#pg2">
        <div>计算</div>
      </a>
      <a class="tab" href="#pg3">
        <div>配额</div>
      </a>
    </div>
    <div class="Notice" id="Notice">
      说明:该页面不兼容IE浏览器
    </div>
    <script>
      // 头部公告
      const Notice = ID('Notice');
      const writeNotice = str => { Notice.textContent = str };
    </script>
  </header>

  <main>
    <!-- ====================================================== section 1 ===================================================== -->
    <section class="page" id="pg1">

      <style>
        /* =====================  section 1 ====================== */
        #pg1-lt {
          width: 300px;
          max-height: 20em;
          top: 3em;
          position: sticky;
        }

        #pg1-rt {
          padding-left: 2em;
        }
      </style>

      <datalist id="zl-list">
        <option value="柴油">
        <option value="92">
        <option value="95">
        <option value="98">
      </datalist>

      <div id="pg1-two">
        <!--  ========== left side ====================  -->
        <div id="pg1-lt">
          <div>
            <div class="pg1-lt-li"><label for="xm">姓名</label><input type="text" id="pg1-lt-xm"></div>
            <div class="pg1-lt-li"><label for="zl">类型</label><input list="zl-list" id="pg1-lt-zl"></div>
            <div class="pg1-lt-li"><label for="je">金额</label><input type="number" id="pg1-lt-je"></div>
            <div class="pg1-lt-li">
              <button id="pg1-lt-billAdd">录入</button>
              <button id="pg1-lt-billLoad">批量录入</button>
              <button id="pg1-lt-billClear">清除右侧</button>
            </div>

            <div class="pg1-lt-li">
              <textarea rows="20" cols="32" id="pg1-lt-billLines" placeholder="每行数据请按[姓名  类型  金额]的顺序排列"></textarea>
            </div>
          </div>
        </div>

        <!-- <div class="page-splitter"></div> -->
        <!-- ========= right side ======================= -->
        <div id="pg1-rt">
          <div class="right-th">
            <div class="right-td">
              <select name="" id="">
                <option>姓名</option>
              </select>
            </div>
            <div class="right-td">
              <select name="" id="" placeholder="aaaa">
                <option>类型</option>
                <option value="92">92</option>
                <option value="98">98</option>
                <option value="95">95</option>
                <option value="柴油">柴油</option>
              </select>
            </div>
            <div class="right-td">
              <input type="number" max="100" min="0" size="4" value="0">
              <span>≤ 金额 ≤</span>
              <input type="number" max="100" min="0" size="4" value="999">
            </div>
          </div>
          <div id="pg1-rt-ul"></div>
          <!-- <pg1-bill xm="王工2" zl="92" je="324.53" idx="0"></pg1-bill> -->
        </div>
      </div>
      <script>
        // ================= pg1 =========================================================

        // 发票 
        class Bill {
          constructor(xm, zl, je) {
            this.xm = xm; // 姓名
            this.zl = zl; // 种类
            this.je = Number.parseFloat(je); // 金额
          }

          static valid(xm, zl, je) {
            if (!xm) { writeNotice('姓名为空'); return false };
            if (!zl) { writeNotice('类型为空'); return false };
            if (['92', '95', '98', '柴油'].indexOf(zl) === -1) { writeNotice('未能识别的类型'); return false };
            if (Number.isNaN(Number.parseFloat(je))) { writeNotice('未能识别的金额'); return false };
            return true;
          }
        };

        /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         ** *                                                               *
         ** *                  All  Bills                                   *
         ** *                                                               *
         ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         */
        const BillList = new LocalDAO('BillList');

        const initPg1Right = async (clear = true, xm = "", zl = "") => {
          let bList = Array.from(await BillList.all());
          const pg1r = ID('pg1-rt-ul');
          // clear
          pg1r.innerHTML = '';

          /**
           * reverse() is't match idx.
           * use for
          bList.reverse().forEach((bill, idx) => {
            pg1r.innerHTML = `<pg1-bill idx="${idx}" xm="${bill.xm}" zl="${bill.zl}" je="${bill.je}"></pg1-bill>` + pg1r.innerHTML;
          });
          */

          if (!!clear) {

          }

          let inHstr = '';
          for (let i = bList.length - 1; i >= 0; i--) {
            inHstr += `<pg1-bill idx="${i}" xm="${bList[i].xm}" zl="${bList[i].zl}" je="${bList[i].je}"></pg1-bill>`;
          }

          pg1r.innerHTML = inHstr;

        }

        // Load Bill datas.
        setTimeout(() => { initPg1Right(); }, 200);

        // =================  Add Bill Data =========

        ID('pg1-lt-billAdd').addEventListener('click', async () => {
          let xm = ID('pg1-lt-xm').value;
          let zl = ID('pg1-lt-zl').value;
          let je = Number.parseFloat(ID('pg1-lt-je').value);

          if (!Bill.valid(xm, zl, je)) return null;

          await BillList.add(new Bill(xm, zl, je));
          await initPg1Right();
          alert('添加成功'); // In case of Click twice
          return writeNotice('添加成功');
        });

        /**
         * Load Bill Datas
         */
        ID('pg1-lt-billLoad').addEventListener('click', async () => {
          let raw = ID('pg1-lt-billLines').value
          if (!raw) return null;

          let lines = raw.split('\n'), success = [];

          for (const line of lines) {
            if (!line) continue;

            let xm, zl, je;

            [xm, zl, je] = line.replace(/\s/g, '#').split('#');

            if (!Bill.valid(xm, zl, je)) continue;

            success.push(new Bill(xm, zl, je));
          }

          if (success.length > 0) {
            await BillList.load(success);
            alert(`成功导入${success.length}行`);
            writeNotice(`成功导入${success.length}行`);
            initPg1Right();
          } else {
            writeNotice('请检测所有录入的数据格式');
          }

        });

        ID('pg1-lt-billClear').addEventListener('click', async () => {
          if (!window.confirm('右侧所有录入的票据信息将会被全部清除，确认该操作吗？')) return null;

          await BillList.clear();
          await initPg1Right();
          return writeNotice('已完全清除');
        });

      </script>
      <!-- ============= Template bill ==================== -->
      <template id="tp-bill">
        <style>
          #tp-bill-row {
            display: flex;
            margin: .5em;
            padding: .5em;
            border-radius: var(--SMBR);
          }

          #tp-bill-row input {
            border: none;
            margin: 0;
            padding: .2em;
            font-size: larger;
          }

          #tp-bill-row button {
            padding-left: 1em;
            font-size: larger;
            color: #FFF;
            border: none;
            background-color: transparent;
          }

          :host([zl="92"]) #tp-bill-row {
            background-color: var(--OL92);
          }

          :host([zl="95"]) #tp-bill-row {
            background-color: var(--OL95);
          }

          :host([zl="98"]) #tp-bill-row {
            background-color: var(--OL98);
          }

          :host([zl="柴油"]) #tp-bill-row {
            background-color: var(--OL05);
          }
        </style>
        <datalist id="zl-list">
          <option value="柴油">
          <option value="92">
          <option value="95">
          <option value="98">
        </datalist>
        <div id="tp-bill-row">
          <input type="text" id="tp-bill-xm" readonly>
          <input list="zl-list" id="tp-bill-zl" readonly>
          <input type="number" id="tp-bill-je" min="0" readonly>
          <button id="tp-bill-sc">X</button>
        </div>

      </template>

      <!-- ============= Script Bill in pg1 =============== -->
      <script>
        class Pg1Bill extends HTMLElement {
          constructor() {
            super();

            this.idx = this.getAttribute('idx');

            let template = document.getElementById('tp-bill');
            // let tp_content = template.content;
            // this.appendChild(tp_content);

            let shadow = this.attachShadow({ mode: 'closed' });

            let tp_content = template.content.cloneNode(true);

            this.$xm = tp_content.getElementById('tp-bill-xm');
            this.$zl = tp_content.getElementById('tp-bill-zl');
            this.$je = tp_content.getElementById('tp-bill-je');

            this.$xm.value = this.getAttribute('xm');
            this.$zl.value = this.getAttribute('zl');
            this.$je.value = this.getAttribute('je');

            [this.$xm, this.$zl, this.$je].forEach(ipt => bindEdit(ipt, async e => {
              let [xm, zl, je] = [this.$xm.value, this.$zl.value, this.$je.value];
              if (!Bill.valid(xm, zl, je)) {
                writeNotice('输入数据有误');
              } else {
                await BillList.edit(this.idx, new Bill(this.$xm.value, this.$zl.value, this.$je.value));
                writeNotice('已修改');
              }
              await initPg1Right();
            }))

            bindDel(tp_content.getElementById('tp-bill-sc'), async e => {
              if (!window.confirm('删除当前发票？')) return null;

              await BillList.delete(this.idx);
              initPg1Right();
              writeNotice('已修改');
            });

            shadow.appendChild(tp_content);
          }

          // get idx() { return this.idx; }
          // set idx(val) { this.idx = val; this.setAttribute('idx', val) }

          // get xm() { return this.$xm.value; }
          // set xm(val) { this.setAttribute('xm', val) }

          // get zl() { return this.$zl.value; }
          // set zl(val) { this.setAttribute('zl', val) }

          // get je() { return this.$je.value; }
          // set je(val) { this.setAttribute('je', val) }

        }

        customElements.define('pg1-bill', Pg1Bill);

      </script>
    </section>


    <!-- ====================================================== section 2 ===================================================== -->
    <section class="page" id="pg2">
      <style>
        :root {
          --PG2_UP_H: 16em;
          --PG2_DOWN_H: 20em;
          --PG2_FT_W: 75em;
        }

        #pg2-up,
        #pg2-down {
          width: 100%;
          padding: 0.5em;
          box-sizing: border-box;
          overflow: visible auto;
          position: absolute;
          z-index: 20;
          display: block;
          /* display: none; */
        }

        #pg2-up {
          top: 0;
          height: var(--PG2_UP_H);
          background: #F0F9;
        }

        #pg2-down {
          top: var(--PG2_UP_H);
          height: var(--PG2_DOWN_H);
          ;
          background: #FF09;
        }

        #pg2-foot {
          display: flex;
          max-width: 75em;
          height: 3em;
          margin: auto;
          padding: .5em;
          background: #00F6;
        }

        #pg2-private {
          display: flex;
          position: relative;
          flex-wrap: wrap;
          width: 100%;
          height: calc(var(--PG2_UP_H) + var(--PG2_DOWN_H));
          /* background: #0F06; */
          overflow: hidden auto;
        }

        #pg2-public {
          display: flex;
          padding: 0.2em;
          background: #00F6;
        }
      </style>

      <script>
        // ============ pg2 Core Logic  =======================

        /**
         * 
         */
        class BillSet {
          constructor() {
            this.bills = new Set();
            this.sum = 0;
          }

          getBill(idx) {
            return BillList.data[idx];
          }

          // BillList Index Save Only
          add(idx) {
            let flag = this.bills.add(idx);
            this.calc();
            return flag;
          }

          del(idx) {
            let flag = this.bills.delete(idx);
            this.calc();
            return flag;
          }

          calc() {
            this.sum = 0;
            for (let i = 0; i < BillList.data.length; i++) {
              if (this.bills.has(i)) this.sum += Number.parseFloat(BillList.data[i].je)
            }
          }

        }

        /**
         * 
         */
        class PublicSet extends BillSet {
          constructor(zl) {
            super();
            this.zl = zl;
          }

          add(idx) {
            bill = getBill(idx);
            if (bill.zl !== this.zl) return false;
            return super.add(idx);
          }

        }

        /**
         * 
         */
        class PrivateSet extends BillSet {
          constructor(xm) {
            super();
            this.xm = xm;
            this.zl = null;
          }

          add(idx) {
            bill = getBill(idx);
            if (this.bills.size === 0) {
              this.zl = bill.zl;
              return super.add(idx);
            } else if (bill.zl !== this.zl) {
              return false;
            }
          }

          del(idx) {
            let flag = super.del(idx);
            if (this.bills.size === 0) this.zl = null;
            return flag;
          }

        }

        // 
        const [ps92, ps95, ps98, ps00] = [new PublicSet('92'), new PublicSet('95'), new PublicSet('98'), new PublicSet('柴油')];
        const PublicMap = { '92': ps92, '95': ps95, '98': ps98, '柴油': ps00 };

        // Will init dinamic
        const PrivateMap = {};


        ID('pg2').addEventListener('mouseEnter', () => {
          // writeNotice('')
        });

        document.querySelectorAll('div.pg2-lt-slot').forEach(elm => {
          elm.addEventListener('dragover', async function (ev) {
            ev.preventDefault();
          });

          elm.addEventListener('drop', async function (ev) {
            ev.preventDefault();
            let data = ev.dataTransfer.getData("Text");
            ev.currentTarget.appendChild(document.getElementById(data));
          });

        })

      </script>

      <div id="pg2-up">
        <pg2-bd id="bd_01" je="99" zl="98"></pg2-bd>
        <pg2-bd id="bd_02" je="97" zl="98"></pg2-bd>
        <pg2-bd id="bd_03" je="93" zl="98"></pg2-bd>
        <pg2-bd id="bd_04" je="92" zl="98"></pg2-bd>
        <pg2-bd id="bd_05" je="89" zl="98"></pg2-bd>

      </div>

      <div id="pg2-down"></div>

      <div id="pg2-private">
        <pg2-private id="calc_01" xm="王工1" pe="1900.55" zl="">
          <div class="pg2-lt-slot" slot="bd" xm="王工1" pc="calc"></div>
        </pg2-private>
        <pg2-private id="calc_02" xm="王工2" pe="1700" zl="">
          <div class="pg2-lt-slot" slot="bd" xm="王工2" pc="calc"></div>
        </pg2-private>
      </div>

      <div id="pg2-foot">
        <div id="pg2-public">
          <pg2-public sum="0" zl="92">
            <div class="pg2-lt-slot" slot="bd" zl="92" pc="pub"></div>
          </pg2-public>
          <pg2-public sum="0" zl="95">
            <div class="pg2-lt-slot" slot="bd" zl="95" pc="pub"></div>
          </pg2-public>
          <pg2-public sum="0" zl="98">
            <div class="pg2-lt-slot" slot="bd" zl="98" pc="pub"></div>
          </pg2-public>
          <pg2-public sum="0" zl="柴油">
            <div class="pg2-lt-slot" slot="bd" zl="柴油" pc="pub"></div>
          </pg2-public>
        </div>
        <div id="pg2-btns">
          <button>计算</button>
        </div>
      </div>


      <!-- ============= Template Pg2 Up ==================== -->
      <template id="tp-up">
        <style>
          :host {
            --PRIVATE_WIDTH: 40em;
          }

          #tp-up-row {
            margin: .5em;
            padding: .5em;
            border-radius: var(--SMBR);
          }

          :host([zl=""]) #tp-up-row,
          :host([zl=""]) #tp-up-fill {
            color: var(--OL00);
            background-color: var(--OL00);
          }

          :host([zl="92"]) #tp-up-row,
          :host([zl="92"]) #tp-up-fill {
            color: var(--OL92);
            background-color: var(--OL92);
          }

          :host([zl="95"]) #tp-up-row,
          :host([zl="95"]) #tp-up-fill {
            color: var(--OL95);
            background-color: var(--OL95);
          }

          :host([zl="98"]) #tp-up-row,
          :host([zl="98"]) #tp-up-fill {
            color: var(--OL98);
            background-color: var(--OL98);
          }

          :host([zl="柴油"]) #tp-up-row,
          :host([zl="柴油"]) #tp-up-fill {
            color: var(--OL05);
            background-color: var(--OL05);
          }

          #tp-up-hd {
            display: flex;
            padding: .2em;
            justify-content: flex-start;
            align-items: center;
            font-size: larger;
            background-color: #FFF;
            border-radius: var(--SMBR);
          }

          #tp-up-xm,
          #tp-up-pe,
          #tp-up-bar,
          #tp-up-cls {
            flex-shrink: 0;
          }

          #tp-up-xm {
            width: 3em;
            padding-left: .5em;
          }

          #tp-up-pe {
            width: 8em;
            text-align: right;
          }

          #tp-up-bar {
            padding: .2em;
            width: 20em;
            margin-left: 1em;
            border-style: solid;
            border-radius: var(--SMBR);
          }

          #tp-up-fill {
            box-sizing: content-box;
            height: 0.5em;
            line-height: 1.6em;
            border-radius: var(--SMBR);
          }

          #tp-up-cls {
            margin-left: .5em;
          }
        </style>
        <div id="tp-up-row">
          <div id="tp-up-hd">
            <div id="tp-up-xm"></div>
            <div id="tp-up-pe"></div>
            <div id="tp-up-bar">
              <div id="tp-up-fill"></div>
            </div>
            <div id="tp-up-cls">X</div>
          </div>
          <div id="tp-up-bd">
            <slot name="bd"></slot>
          </div>
        </div>

      </template>

      <!-- ============= Script Pg2 up ==================== -->
      <script>
        class Pg2Up extends HTMLElement {
          constructor() {
            super();

            let template = document.getElementById('tp-up');
            let shadow = this.attachShadow({ mode: 'open' });

            let tp_content = template.content.cloneNode(true);

            this.$xm = tp_content.getElementById('tp-up-xm');
            this.$pe = tp_content.getElementById('tp-up-pe');
            this.$fill = tp_content.getElementById('tp-up-fill');
            this.$xm.textContent = this.getAttribute('xm');

            this.zl = this.getAttribute('zl');
            this.pe = Number.parseFloat(this.getAttribute('pe'));
            this.sum = 1500.99;

            this.calc();

            bindDel(tp_content.getElementById('tp-up-cls'), async () => {
              if (!confirm('将此人员已分配的所有发票都归还于公共库？')) return;
              alert('yxgg')
            }, '所有发票都归还于公共库');

            shadow.appendChild(tp_content);

          }

          calc() {
            this.$pe.textContent = `${this.sum}/${this.pe}`;
            this.$fill.style.width = `up(20em * ${this.sum / this.pe})`;
          }
        }

        customElements.define('pg2-up', Pg2Up);

      </script>

      <!-- ============= Template Pg2 Down ==================== -->
      <template id="tp-down">
        <style>
          :host {
            --PUBLIC_WIDTH: 30em;
          }

          #tp-down-row {
            margin: .5em;
            padding: .5em;
            border-radius: var(--SMBR);
          }

          :host([zl="92"]) #tp-down-row {
            color: var(--OL92);
            background-color: var(--OL92);
          }

          :host([zl="95"]) #tp-down-row {
            color: var(--OL95);
            background-color: var(--OL95);
          }

          :host([zl="98"]) #tp-down-row {
            color: var(--OL98);
            background-color: var(--OL98);
          }

          :host([zl="柴油"]) #tp-down-row {
            color: var(--OL05);
            background-color: var(--OL05);
          }

          #tp-down-hd {
            display: flex;
            padding: .2em;
            justify-content: flex-start;
            align-items: center;
            font-size: larger;
            color: #FFF;
            border-radius: var(--SMBR);
          }

          #tp-down-zl,
          #tp-down-sum {
            flex-shrink: 0;
          }

          #tp-down-zl {
            width: 2em;
            padding-left: .5em;
          }

          #tp-down-sum {
            width: 6em;
            text-align: right;
          }
        </style>
        <div id="tp-down-row">
          <div id="tp-down-hd">
            <div id="tp-down-zl"></div>
            <div id="tp-down-sum"></div>
          </div>
          <div id="tp-down-bd">
            <slot name="bd"></slot>
          </div>
        </div>

      </template>

      <!-- ============= Script Pg2 Down ==================== -->
      <script>
        class Pg2Down extends HTMLElement {
          constructor() {
            super();

            let template = document.getElementById('tp-down');
            let shadow = this.attachShadow({ mode: 'open' });

            let tp_content = template.content.cloneNode(true);

            this.$zl = tp_content.getElementById('tp-down-zl');
            this.$sum = tp_content.getElementById('tp-down-sum');
            this.$bd = tp_content.getElementById('tp-down-bd');

            this.$zl.textContent = this.zl = this.getAttribute('zl');
            this.sum = 0;

            this.calc();

            shadow.appendChild(tp_content);

          }

          calc() {
            this.$sum.textContent = `${this.sum}`;
          }
        }

        customElements.define('pg2-down', Pg2Down);

      </script>

      <!-- ============= Template Pg2 Private ==================== -->
      <template id="tp-private">
        <style>
          :host {
            --PRIVATE_WIDTH: 40em;
          }

          #tp-private-row {
            margin: 0 0.5em;
            padding: 0.2em;
            border-radius: var(--SMBR);
          }

          :host([zl=""]) #tp-private-row,
          :host([zl=""]) #tp-private-fill {
            color: var(--OL00);
            background-color: var(--OL00);
          }

          :host([zl="92"]) #tp-private-row,
          :host([zl="92"]) #tp-private-fill {
            color: var(--OL92);
            background-color: var(--OL92);
          }

          :host([zl="95"]) #tp-private-row,
          :host([zl="95"]) #tp-private-fill {
            color: var(--OL95);
            background-color: var(--OL95);
          }

          :host([zl="98"]) #tp-private-row,
          :host([zl="98"]) #tp-private-fill {
            color: var(--OL98);
            background-color: var(--OL98);
          }

          :host([zl="柴油"]) #tp-private-row,
          :host([zl="柴油"]) #tp-private-fill {
            color: var(--OL05);
            background-color: var(--OL05);
          }

          #tp-private-hd {
            display: flex;
            padding: .2em;
            justify-content: flex-start;
            align-items: center;
            font-size: larger;
            background-color: #FFF;
            border-radius: var(--SMBR);
          }

          #tp-private-xm,
          #tp-private-pe,
          #tp-private-bar,
          #tp-private-cls {
            flex-shrink: 0;
          }

          #tp-private-xm {
            width: 3em;
            padding-left: .5em;
          }

          #tp-private-pe {
            width: 8em;
            text-align: right;
          }

          #tp-private-bar {
            padding: .2em;
            width: 20em;
            margin-left: 1em;
            border-style: solid;
            border-radius: var(--SMBR);
          }

          #tp-private-fill {
            box-sizing: content-box;
            height: 0.5em;
            line-height: 1.6em;
            border-radius: var(--SMBR);
          }

          #tp-private-cls {
            margin-left: .5em;
          }
        </style>
        <div id="tp-private-row">
          <div id="tp-private-hd">
            <div id="tp-private-xm"></div>
            <div id="tp-private-pe"></div>
            <div id="tp-private-bar">
              <div id="tp-private-fill"></div>
            </div>
            <div id="tp-private-cls">X</div>
          </div>
          <div id="tp-private-bd">
            <slot name="bd"></slot>
          </div>
        </div>

      </template>

      <!-- ============= Script Pg2 Private ==================== -->
      <script>
        class Pg2Private extends HTMLElement {
          constructor() {
            super();

            let template = document.getElementById('tp-private');
            let shadow = this.attachShadow({ mode: 'open' });

            let tp_content = template.content.cloneNode(true);

            this.$xm = tp_content.getElementById('tp-private-xm');
            this.$pe = tp_content.getElementById('tp-private-pe');
            this.$fill = tp_content.getElementById('tp-private-fill');
            this.$xm.textContent = this.getAttribute('xm');

            this.zl = this.getAttribute('zl');
            this.pe = Number.parseFloat(this.getAttribute('pe'));
            this.sum = 1500.99;

            this.private();

            bindDel(tp_content.getElementById('tp-private-cls'), async () => {
              if (!confirm('将此人员已分配的所有发票都归还于公共库？')) return;
              alert('yxgg')
            }, '所有发票都归还于公共库');

            shadow.appendChild(tp_content);

          }

          private() {
            this.$pe.textContent = `${this.sum}/${this.pe}`;
            this.$fill.style.width = `private(20em * ${this.sum / this.pe})`;
          }
        }

        customElements.define('pg2-private', Pg2Private);

      </script>

      <!-- ============= Template Pg2 Public ==================== -->
      <template id="tp-public">
        <style>
          :host {
            --PUBLIC_WIDTH: 30em;
          }

          :host([zl="92"]) #tp-public-bd {
            /* color: var(--OL92); */
            background-color: var(--OL92);
          }

          :host([zl="95"]) #tp-public-bd {
            /* color: var(--OL95); */
            background-color: var(--OL95);
          }

          :host([zl="98"]) #tp-public-bd {
            /* color: var(--OL98); */
            background-color: var(--OL98);
          }

          :host([zl="柴油"]) #tp-public-bd {
            /* color: var(--OL05); */
            background-color: var(--OL05);
          }

          #tp-public-bd {
            margin: 0 0.1em;
            padding: 0.2em;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #FFF;
            border-radius: var(--SMBR);
          }

          #tp-public-zl,
          #tp-public-count,
          #tp-public-sum {
            flex-shrink: 0;
            text-align: center;
          }

          #tp-public-zl ,#tp-public-count {
           width: 2em;
          }
          #tp-public-count{
            border-left: 2px solid #FFF;
            border-right: 2px solid #FFF;
          }
          #tp-public-sum {
           width: 6em;
          }
        </style>
        <div id="tp-public-bd">
            <div id="tp-public-zl"></div>
            <div id="tp-public-count"></div>         
            <div id="tp-public-sum"></div>         
        </div>

      </template>

      <!-- ============= Script Pg2 Public ==================== -->
      <script>
        class Pg2Public extends HTMLElement {
          constructor() {
            super();

            let template = document.getElementById('tp-public');
            let shadow = this.attachShadow({ mode: 'open' });

            let tp_content = template.content.cloneNode(true);

            this.$zl = tp_content.getElementById('tp-public-zl');
            this.$count = tp_content.getElementById('tp-public-count');
            this.$sum = tp_content.getElementById('tp-public-sum');
            this.$bd = tp_content.getElementById('tp-public-bd');

            this.$zl.textContent = this.zl = this.getAttribute('zl');
            this.sum = 0;

            this.billSet = PublicMap[this.zl]
            // this.calc();

            shadow.appendChild(tp_content);

          }

          calc() {
            this.$sum.textContent = `${this.sum}`;
          }
        }

        customElements.define('pg2-public', Pg2Public);

      </script>

      <!-- ============= Template Bill Drops ==================== -->
      <template id="tp-bd">
        <style>
          #tp-bd-row {
            margin: .5em;
            padding: .2em;
            width: 6em;
            text-align: center;
            border-radius: var(--SMBR);
          }

          #tp-bd-je {
            color: #FFF;
          }

          :host([zl="92"]) #tp-bd-row {
            background-color: var(--OL92);
          }

          :host([zl="95"]) #tp-bd-row {
            background-color: var(--OL95);
          }

          :host([zl="98"]) #tp-bd-row {
            background-color: var(--OL98);
          }

          :host([zl="柴油"]) #tp-bd-row {
            background-color: var(--OL05);
          }
        </style>
        <div id="tp-bd-row" draggable="true">
          <span id="tp-bd-je"></span>
        </div>

      </template>

      <!-- ============= Script Bill Drops ==================== -->
      <script>
        class Pg2BD extends HTMLElement {
          constructor() {
            super();

            let template = document.getElementById('tp-bd');
            let shadow = this.attachShadow({ mode: 'open' });

            let tp_content = template.content.cloneNode(true);

            this.$je = tp_content.getElementById('tp-bd-je');
            this.je = this.$je.textContent = this.getAttribute('je');
            this.zl = this.getAttribute('zl');

            this.$bd = tp_content.getElementById('tp-bd-row');
            this.$bd.setAttribute('bid', this.id);

            // ---------------- Drag ------------------------
            this.$bd.addEventListener('dragstart', ev => {
              ev.dataTransfer.setData("Text", ev.target.getAttribute('bid'));
            });

            shadow.appendChild(tp_content);

          }
        }

        customElements.define('pg2-bd', Pg2BD);

      </script>

    </section>
    <!-- ====================================================== section 3 ===================================================== -->
    <section class="page" id="pg3">
      <style>
        /* =====================  section 3 ====================== */

        #pg3-lt {
          max-height: 20em;
          top: 3em;
          position: sticky;
        }
      </style>
      <div id="pg3-two">
        <div id="pg3-lt">
          <div class="pg3-lt-li"><label for="xm">姓名</label><input type="text" id="pg3-lt-xm"></div>
          <div class="pg3-lt-li"><label for="pe">配额</label><input type="number" id="pg3-lt-pe"></div>
          <div class="pg3-lt-li">
            <button id="pg3-lt-qutoaAdd">添加</button>
          </div>
        </div>
        <div id="pg3-rt">
          <div class="right-th">
            <div class="right-td"><span>姓名</span></div>
            <div class="right-td"><span>配额</span></div>
            <div class="right-td"><span>合计</span></div>
          </div>
          <div id="pg3-rt-ul">
            <!-- <pg3-quota xm="王工2" pe="900" lj="1230" ></pg3-quota> -->
          </div>
        </div>
      </div>

      <!-- ============= Template quto ==================== -->
      <template id="tp-quato">
        <style>
        </style>
        <div id="tp-quato-row">
          <input type="text" id="tp-quato-xm" readonly>
          <input type="number" id="tp-quato-pe" min="0" readonly>
          <input type="number" id="tp-quato-lj" min="0" readonly>
          <button id="tp-quato-sc">X</button>
        </div>
      </template>

      <!-- ============== Script Quota in pg3 ============ -->
      <script>
        class Pg3Quota extends HTMLElement {
          constructor() {
            super();

            this.idx = this.getAttribute('idx');

            let template = document.getElementById('tp-quato');
            // let tp_content = template.content;
            // this.appendChild(tp_content);

            let shadow = this.attachShadow({ mode: 'closed' });

            let tp_content = template.content.cloneNode(true);

            this.$xm = tp_content.getElementById('tp-quato-xm');
            this.$pe = tp_content.getElementById('tp-quato-pe');
            this.$lj = tp_content.getElementById('tp-quato-lj');

            this.$xm.value = this.getAttribute('xm');
            this.$pe.value = this.getAttribute('pe');
            // this.$lj.value = this.getAttribute('lj');

            Promise.resolve(BillList.all()).then(bills => {

              this.$lj.value = bills.filter(b => b.xm = this.$xm.value)
                .reduce((pre, cObj) => pre + Number.parseFloat(cObj.je), 0);
            })


            /**
             * Can't change xm , need to delete. 
             */
            // bindEdit(this.$pe, async e => {
            //   let [xm, pe] = [this.$xm.value, this.$pe.value];
            //   if (!Quota.valid(xm, pe)) {
            //     writeNotice('输入数据有误');
            //   } else {
            //     await QutoaList.edit(this.idx, new Bill(this.$xm.value, this.$pe.value));
            //     writeNotice('已修改');
            //   }
            //   await initPg3Right();
            // })

            bindDel(tp_content.getElementById('tp-quato-sc'), async e => {
              if (!window.confirm('对应的所有发票会被清除，确认该操作吗？')) return null;

              await BillList.read();

              BillList.data = BillList.data.filter(b => b.xm !== this.$xm.value);

              await BillList.save()

              await QutoaList.delete(this.idx);

              initPg3Right();

              writeNotice('已修改');
            });

            shadow.appendChild(tp_content);
          }
        }

        customElements.define('pg3-quota', Pg3Quota);
      </script>

      <script>
        // ========================= pg3 =======================

        // 配额
        class Quota {
          constructor(xm, pe) {
            this.xm = xm;
            this.pe = Number.parseFloat(pe);
          }
          static valid(xm, pe) {
            if (!xm) { writeNotice('姓名为空'); return false };
            if (Number.isNaN(Number.parseFloat(pe))) { writeNotice('未能识别的配额'); return false };
            return true;
          }
        };

        /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         ** *                                                               *
         ** *                  All  Qutoas                                  *
         ** *                                                               *
         ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         */
        const QutoaList = new LocalDAO('QutoaList');

        ID('pg2').addEventListener('focus', () => {
          // writeNotice('')
        });

        ID('pg3-lt-qutoaAdd').addEventListener('click', async () => {
          let xm = ID('pg3-lt-xm').value;
          let pe = Number.parseFloat(ID('pg3-lt-pe').value);

          if (!Quota.valid(xm, pe)) return null;

          await QutoaList.add(new Quota(xm, pe));
          await initPg3Right();
          alert('添加成功'); // In case of Click twice
          return writeNotice('添加成功');
        });

        const initPg3Right = async (clear = true, xm = "", zl = "") => {
          let qList = Array.from(await QutoaList.all());
          const pg3r = ID('pg3-rt-ul');
          // clear
          pg3r.innerHTML = '';

          let inHstr = ''
          qList.forEach((qt, idx) => {
            inHstr = `<pg3-quota idx="${idx}" xm="${qt.xm}" pe="${qt.pe}"></pg3-quota>` + inHstr;
          });

          pg3r.innerHTML = inHstr;
        }

        // Load Bill datas.
        setTimeout(() => { initPg3Right(); }, 200);

      </script>
    </section>
  </main>

  <footer>

  </footer>

</body>

</html>